use std::any::Any;
use std::sync::Arc;
use std::time::{Duration, Instant};
use async_trait::async_trait;
use tokio::time::sleep;
use uuid::Uuid;

use protoactor_rs::actor::{Actor, ActorContext, ActorError, DefaultActorContext, PID, Props};
use protoactor_rs::system::{ActorSystem, RequestMessage, RequestEnvelope};

// 定义消息类型 - 添加Debug以方便跟踪
#[derive(Clone, Debug)]
struct Ping {
    id: usize,
}

#[derive(Clone, Debug)]
struct Pong {
    id: usize,
}

// 定义EchoActor，只是简单地响应消息
#[derive(Clone)]
struct EchoActor;

#[async_trait]
impl Actor for EchoActor {
    type Context = DefaultActorContext;

    async fn receive(&self, ctx: &mut Self::Context, msg: Box<dyn Any + Send>) -> Result<(), ActorError> {
        println!("EchoActor received a message, type_id: {:?}", msg.type_id());
        println!("EchoActor current message in context, type_id: {:?}", ctx.message().type_id());
        println!("RequestEnvelope TypeId: {:?}", std::any::TypeId::of::<RequestEnvelope>());
        
        // 首先检查是否是 RequestEnvelope
        if msg.type_id() == std::any::TypeId::of::<RequestEnvelope>() {
            println!("EchoActor received a RequestEnvelope");
            
            // 尝试将消息转换为 RequestEnvelope
            if let Ok(envelope) = msg.downcast::<RequestEnvelope>() {
                println!("EchoActor successfully downcast to RequestEnvelope");
                
                // 获取内部的 RequestMessage
                let request = envelope.request;
                println!("Inner message type_id: {:?}", request.message.type_id());
                
                // 检查内部消息是否是 Ping
                if request.message.type_id() == std::any::TypeId::of::<Ping>() {
                    if let Ok(ping) = request.message.downcast::<Ping>() {
                        println!("EchoActor received Ping {:?} inside RequestEnvelope", ping);
                        
                        // 创建 Pong 响应
                        let pong = Pong { id: ping.id };
                        println!("EchoActor created Pong response with id: {}", pong.id);
                        
                        // 直接发送响应
                        match request.sender.send(Box::new(pong)) {
                            Ok(_) => println!("EchoActor successfully sent Pong response"),
                            Err(_) => println!("EchoActor failed to send response: sender dropped"),
                        }
                    } else {
                        println!("EchoActor failed to downcast inner message to Ping");
                    }
                } else {
                    println!("EchoActor received unknown message type inside RequestEnvelope");
                    
                    // 发送一个默认响应
                    let pong = Pong { id: 0 };
                    match request.sender.send(Box::new(pong)) {
                        Ok(_) => println!("EchoActor sent default Pong response"),
                        Err(_) => println!("EchoActor failed to send default response: sender dropped"),
                    }
                }
            } else {
                println!("EchoActor failed to downcast to RequestEnvelope");
            }
        }
        // 尝试将消息转换为Ping
        else if let Ok(ping) = msg.downcast::<Ping>() {
            println!("EchoActor received Ping {:?}, responding with Pong", ping);
            
            // 确保回复消息包含相同的ID
            let pong = Pong { id: ping.id };
            
            // 使用常规方式响应
            ctx.respond(pong);
            
            println!("EchoActor sent response for ping {}", ping.id);
        } else {
            println!("EchoActor received unknown message type");
        }
        
        Ok(())
    }
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    println!("Starting simple benchmark...");
    
    // 创建actor系统
    let system = ActorSystem::new().unwrap();
    println!("Actor system created");
    
    // 创建EchoActor
    let echo_props = Props::from_producer(|| EchoActor {});
    let echo_pid = system.spawn::<EchoActor>(echo_props).await?;
    println!("EchoActor spawned with PID: {:?}", echo_pid);
    
    // 发送和接收消息的次数
    let iterations = 10;
    println!("Will send {} messages", iterations);
    
    // 等待一段时间，确保Actor已经启动
    sleep(Duration::from_millis(500)).await;
    println!("Starting message exchange...");
    
    // 测量性能
    let start = Instant::now();
    let mut success_count = 0;
    let mut failure_count = 0;
    
    for i in 0..iterations {
        println!("Sending message {}/{}", i+1, iterations);
        
        // 创建带有ID的Ping消息
        let ping = Ping { id: i };
        
        // 发送请求并等待响应，增加超时时间
        let response = system.request::<Pong>(&echo_pid, ping, Duration::from_secs(10)).await;
        
        match response {
            Ok(pong) => {
                success_count += 1;
                println!("Received response for message {}/{}: {:?}", i+1, iterations, pong);
                
                // 在消息之间添加短暂延迟，避免消息堆积
                sleep(Duration::from_millis(100)).await;
            },
            Err(e) => {
                failure_count += 1;
                println!("Error receiving response for message {}/{}: {:?}", i+1, iterations, e);
            },
        }
    }
    
    let elapsed = start.elapsed();
    println!("All messages processed in {:?}", elapsed);
    println!("Success: {}, Failures: {}", success_count, failure_count);
    
    if success_count > 0 {
        println!("Average time per successful message: {:?}", elapsed / success_count as u32);
    }
    
    // 停止actor前等待一段时间，确保所有消息都已处理
    println!("Waiting for any pending messages to be processed...");
    sleep(Duration::from_secs(1)).await;
    
    // 停止actor
    println!("Stopping EchoActor...");
    system.stop(&echo_pid).await?;
    println!("EchoActor stopped");
    
    // 等待一会儿，确保所有资源都被释放
    sleep(Duration::from_millis(500)).await;
    println!("Benchmark completed successfully");
    
    Ok(())
} 